import { type HTMLAttributes, type PropType, computed, defineComponent, inject } from "vue";
import { useClickAnimating } from '../use/useClickAnimating';
import Loading from '../inner/Loading';
import { BUTTON_GROUP_CONTEXT } from "../ButtonGroup";

export interface ButtonProps extends Omit<HTMLAttributes, 'type'>{
    type?: 'primary'|'secondary'|'tertiary'|'success'|'error'|'danger'|'warning'|'default',
    theme?: 'light'|'solid'|'borderless'|'outline'|'dashed'
    block?: boolean,
    size?: 'small'|'default'|'large',
    active?: boolean,
    shape?: 'square'|'round'|'circle'
    disabled?: boolean,
    loading?: boolean,
    icon?: JSX.Element,
    iconAlign?: 'left' | 'right',
};

export default defineComponent({
    name: 'Button',
    props: {
        type: {type: String as PropType<ButtonProps['type']>},
        theme: {type: String as PropType<ButtonProps['theme']>},
        shape: {type: String as PropType<ButtonProps['shape']>},
        disabled: { type: Boolean as PropType<ButtonProps['disabled']>, default: undefined},
        block: { type: Boolean as PropType<ButtonProps['block']>},
        size: { type: String as PropType<ButtonProps['size']>},
        active: { type: Boolean as PropType<ButtonProps['active']> },
        loading: { type: Boolean as PropType<ButtonProps['loading']> },
        icon: { type: Object as PropType<ButtonProps['icon']> },
        iconAlign: {type: String as PropType<ButtonProps['iconAlign']>, default: 'left'},
    },
    emits: ['click'],
    setup (props: ButtonProps, { emit, slots }) {
        const [animating, setAnimate] = useClickAnimating();
        const ctx: any = inject(BUTTON_GROUP_CONTEXT, {});

        const type = computed(() => props.type || ctx?.type);
        const size = computed(() => props.size || ctx?.size);
        const theme = computed(() => props.theme || ctx?.theme);
        const shape = computed(() => props.shape || ctx?.shape || 'square');
        const disabled = computed(() => props.disabled || ctx?.disabled);

        const classes = computed(() => ({
            'cm-button': true,
            [`cm-button-icon-${props.iconAlign}`]: true,
            'cm-click-animating': animating,
            'cm-button-disabled': disabled.value,
            'cm-button-block': props.block,
            [`cm-button-${type.value}`]: type.value,
            [`cm-button-theme-${theme.value}`]: theme.value,
            [`cm-button-${size.value}`]: size.value,
            'cm-button-active': props.active,
            'cm-button-circle': shape.value === 'circle',
            'cm-button-round': shape.value === 'round',
            'cm-button-icon-only': !!props.icon && !slots.default,
            'cm-button-empty': !props.icon && !slots.default
        }));

        const handleClick = (e: any) => {
            if (disabled.value) {
                return;
            }
            setAnimate();
            emit('click', e);
        };

        return () => (
            <button type="button" class={classes.value} title={props.title} disabled={disabled.value}
                onClick={handleClick}>
                {
                    props.loading ? <Loading /> : (props.icon || slots.icon) && props.iconAlign === 'left' ? <span class="cm-button-icon">{props.icon || slots.icon()}</span> : null
                }
                {
                    slots.default && slots.default()
                }
                {
                    (props.icon || slots.icon) && props.iconAlign === 'right' ? <span class="cm-button-icon">{props.icon || slots.icon()}</span> : null
                }
            </button>
        );
    }
});
